package org.zero.db;

import lombok.experimental.UtilityClass;
import org.zero.PropertiesEnhancer;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.time.Duration;

/**
 * JedisPool 工具类
 *
 * @author Zero
 * 依赖：PropertiesEnhancer 工具类 和 Jedis.jar
 */
@UtilityClass
public class JedisPoolUtil {

    private static final PropertiesEnhancer PROPERTIES_ENHANCER;
    private static final JedisPoolConfig JEDIS_POOL_CONFIG;
    private static JedisPool jedisPool;

    static {
        try {
            PROPERTIES_ENHANCER = new PropertiesEnhancer("redis.properties");
            JEDIS_POOL_CONFIG = new JedisPoolConfig();

            JEDIS_POOL_CONFIG.setMinIdle(PROPERTIES_ENHANCER.getInt("minIdle", 3));
            JEDIS_POOL_CONFIG.setMaxIdle(PROPERTIES_ENHANCER.getInt("maxIdle", 10));
            JEDIS_POOL_CONFIG.setMaxTotal(PROPERTIES_ENHANCER.getInt("maxTotal", 100));
            JEDIS_POOL_CONFIG.setMaxWait(Duration.ofMillis(PROPERTIES_ENHANCER.getLong("maxWaitMillis", 3000)));

            JEDIS_POOL_CONFIG.setTestOnCreate(PROPERTIES_ENHANCER.getBoolean("testOnCreate", false));
            JEDIS_POOL_CONFIG.setTestOnBorrow(PROPERTIES_ENHANCER.getBoolean("testOnBorrow", false));
            JEDIS_POOL_CONFIG.setTestOnReturn(PROPERTIES_ENHANCER.getBoolean("testOnReturn", false));
            JEDIS_POOL_CONFIG.setBlockWhenExhausted(PROPERTIES_ENHANCER.getBoolean("blockWhenExhausted", true));

            JEDIS_POOL_CONFIG.setTestWhileIdle(PROPERTIES_ENHANCER.getBoolean("testWhileIdle", false));
            JEDIS_POOL_CONFIG.setNumTestsPerEvictionRun(PROPERTIES_ENHANCER.getInt("numTestsPerEvictionRun", 5));
            JEDIS_POOL_CONFIG.setTimeBetweenEvictionRuns(Duration.ofMillis(PROPERTIES_ENHANCER.getLong("timeBetweenEvictionRunsMillis", 30000)));
            JEDIS_POOL_CONFIG.setMinEvictableIdleTime(Duration.ofMillis(PROPERTIES_ENHANCER.getLong("minEvictableIdleTimeMillis", 300000)));
            JEDIS_POOL_CONFIG.setSoftMinEvictableIdleTime(Duration.ofMillis(PROPERTIES_ENHANCER.getLong("softMinEvictableIdleTimeMillis", 300000)));

            JEDIS_POOL_CONFIG.setLifo(PROPERTIES_ENHANCER.getBoolean("lifo", true));
        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    public static Jedis getJedis() {
        if (jedisPool == null) {
            jedisPool = new JedisPool(JEDIS_POOL_CONFIG,
                    PROPERTIES_ENHANCER.getString("ip", "localhost"),
                    PROPERTIES_ENHANCER.getInt("port", 6379), PROPERTIES_ENHANCER.getInt("connectionTimeout", 3000),
                    PROPERTIES_ENHANCER.getInt("soTimeout", 2000), PROPERTIES_ENHANCER.getString("password"),
                    PROPERTIES_ENHANCER.getInt("database", 0), null);
        }
        return jedisPool.getResource();
    }

    public static void closeJedis(Jedis redis) {
        if (redis != null) {
            redis.close();
        }
    }

    public static void closeJedisPool() {
        if (jedisPool != null) {
            jedisPool.close();
        }
    }
}